/*
 * @Author: CSG@HYC
 * @Date: 2025-07-19 09:02:51
 * @FilePath: \MDK-ARMe:\Desktop\F1_template\HW\Src\clock.c
 * @Description: HAL库时钟配置函数
 */
#include "clock.h"
/**
 * Relationship between SYSCLK and FLASH minimum Latency
 *      SYSCLK FREQ             Minimum FLASH Latency
 *        <=24MHZ                  FLASH_LATENCY_0
 * 24MHZ < SYSCLK <= 48MHZ         FLASH_LATENCY_1
 * 48MHZ < SYSCLK <= 72MHZ         FLASH_LATENCY_2
 */


/**
 * @description: System Clock Init
 * @return {*}
 */
void HW_Clock_Init(void)
{
    #ifdef __SYSTEM_CLOCK_36MHZ
    // Configure System Clock to 32MHz, Use HSI
    /**
     * HSI RC 8MHz
     *     /2 -> HSI 4MHz
     *        -> PLL PLLMul 9
     *        -> PLLCLK 36MHz
     *        -> AHB Prescaler /1
     *        -> HCLK 36MHz
     *              /1(APB1 Prescaler) -> PCLK1 36MHz
     *              /1(APB2 Prescaler) -> PCLK2 36MHZ              
     */
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;          // Select Clock : HSI
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;                            // Open HSE
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; // HSI deefault value : 4MHZ
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;                        // Open PLL
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;           // Set PLL input source    
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;                       // Set PLL MUL value
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        // TODO 
        // Error_Handle();
    }


    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
    {
        // TODO 
        // Error_Handle();
    }
    #endif


    #ifdef __SYSTEM_CLOCK_64MHZ
    // Configure System Clock to 64MHz, Use HSI
    /**
     * HSI RC 8MHz
     *     /2 -> HSI 4MHz
     *        -> PLL PLLMul 16
     *        -> PLLCLK 64MHz
     *        -> AHB Prescaler /1
     *        -> HCLK 64MHz
     *              /2(APB1 Prescaler) -> PCLK1 32MHz
     *              /1(APB2 Prescaler) -> PCLK2 64MHZ              
     */
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;          // Select Clock : HSI
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;                            // Open HSE
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; // HSI deefault value : 4MHZ
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;                        // Open PLL
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;           // Set PLL input source    
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;                       // Set PLL MUL value
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        // TODO 
        // Error_Handle();
    }


    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        // TODO 
        // Error_Handle();
    }
    #endif

    #ifdef __SYSTEM_CLOCK_72MHZ
    // Configure System Clock to 64MHz, Use HSE
    /**
     * HSE 8MHz
     *     -> PLL PLLMul 
     *     -> PLLCLK 72MHz
     *           -> AHB Prescaler /1
     *           -> HCLK 72MHz
     *                 /2(APB1 Prescaler) -> PCLK1 36MHz
     *                 /1(APB2 Prescaler) -> PCLK2 72MHZ              
     */
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // Select Clock : HSE
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;                    // Open HSE
    RCC_OscInitStruct.HSEPredivValue = RCC_SYSCLK_DIV1;         // According to the external 8MHZ crystal oscillator compose
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;                // Open PLL
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;        // Set PLL input source
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;                // Set PLL MUL value
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        // TODO 
        // Error_Handle();
    }
    
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        // TODO 
        // Error_Handle();
    }
    
    #endif
    /**
     * Default Clock Configure -> Freq 8MHz
     * If define __SYSTEM_CLOCK_64MHZ or __SYSTEM_CLOCK_72MHZ, System Clock will be update to you set value
     */
    // HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
    HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
    // Update Clock
    SystemCoreClockUpdate();
}

